import {CloseCircleOutlined} from '@ant-design/icons';
import {
  FooterToolbar,
  PageContainer,
  ProForm,
  ProFormSelect,
  ProFormText,
  ProFormTextArea
} from '@ant-design/pro-components';
import {Button, Card, Col, Form, message, Popover, Row, Segmented} from 'antd';
import type {FC} from 'react';
import {useState} from 'react';
import {getStressCase, saveStressCasePage, updateStressCasePage} from './service';
import {pageModule} from '../../module/service';
import {history, useModel, useRequest, useSearchParams} from '@umijs/max';
import {getEnvPage} from '@/pages/common-menu/environment/service';
import SIMPLE from './components/SIMPLE';
import JMX from './components/JMX';
import useStyles from './style.style';
import {setKey} from '@/utils';

type InternalNamePath = (string | number)[];

interface ErrorField {
  name: InternalNamePath;
  errors: string[];
}

const AdvancedForm: FC<Record<string, any>> = () => {
  const {styles} = useStyles();
  const [searchParams, setSearchParams] = useSearchParams()
  const id = searchParams.get('id')
  const [form] = Form.useForm()
  const [error, setError] = useState<ErrorField[]>([]);
  const {initialState} = useModel('@@initialState');

  const getErrorInfo = (errors: ErrorField[]) => {
    const errorCount = errors.filter((item) => item.errors.length > 0).length;
    if (!errors || errorCount === 0) {
      return null;
    }
    const scrollToField = (fieldKey: string) => {
      const labelNode = document.querySelector(`label[for="${fieldKey}"]`);
      if (labelNode) {
        labelNode.scrollIntoView(true);
      }
    };
    const errorList = errors.map((err) => {
      if (!err || err.errors.length === 0) {
        return null;
      }
      const key = err.name[0] as 'name' | 'url' | 'owner' | 'approver' | 'dateRange' | 'type';
      return (
        <li key={key} className={styles.errorListItem} onClick={() => scrollToField(key)}>
          <CloseCircleOutlined className={styles.errorIcon}/>
          {/* <div className={styles.errorMessage}>{err.errors[0]}</div>
          <div className={styles.errorField}>{fieldLabels[key]}</div> */}
        </li>
      );
    });
    return (
      <span className={styles.errorIcon}>
        <Popover
          title="表单校验信息"
          content={errorList}
          overlayClassName={styles.errorPopover}
          trigger="click"
          getPopupContainer={(trigger: HTMLElement) => {
            if (trigger && trigger.parentNode) {
              return trigger.parentNode as HTMLElement;
            }
            return trigger;
          }}
        >
          <CloseCircleOutlined/>
        </Popover>
        {errorCount}
      </span>
    );
  };


  const onFinishFailed = (errorInfo: any) => {
    setError(errorInfo.errorFields);
  };

  const {refresh, loading} = useRequest(() => {
    return getStressCase({id, projectId: initialState?.currentProject?.id})
  }, {
    refreshDeps: [id], ready: !!id, onSuccess(data) {
      const newValues: any = {
        ...data,
      }
      try {
        if (newValues?.threadGroupConfig) {
          newValues.threadGroupConfig = JSON.parse(newValues?.threadGroupConfig)
        }
        if (newValues?.header) {
          newValues.header = setKey(JSON.parse(newValues?.header), 'id')
        }
        if (newValues.body) {
          const body = setKey(JSON.parse(newValues.body), 'id')
          newValues[newValues.bodyType] = body
          newValues.body = body
        }
        if (newValues.query) {
          newValues.query = setKey(JSON.parse(newValues.query), 'id')
        }
        if (newValues.assertion) {
          newValues.assertion = setKey(JSON.parse(newValues.assertion))
          newValues.enableAssertionConfig = true
        }
        if(data?.jmxUrl) {
          newValues.jmx = newValues.jmx || {}
          newValues.jmx.jmxUrl = JSON.parse(data?.jmxUrl)
        }
        if (newValues.relation) {
          if (newValues.stressSourceType === 'SIMPLE') {
            newValues.relation = setKey(JSON.parse(newValues.relation))
            newValues.enableParamConfig = true

          } else if (newValues.stressSourceType === 'JMX') {
            newValues.jmx = newValues.jmx || {}
            newValues.jmx.relation = setKey(JSON.parse(newValues.relation))
            newValues.jmx.enableParamConfig = true

          }
        }

      } catch (e) {
        console.log(e)
      }

      form.resetFields()
      console.log(newValues);
      form.setFieldsValue(newValues)
    }
  })

  const onFinish = async (values: Record<string, any>) => {
    const hide = message.loading('正在保存');
    try {
      const api = id ? updateStressCasePage : saveStressCasePage

      let params: any = {
        ...values,
        id: id,
        projectId: initialState?.currentProject?.id,

      }
      console.log(values);

      if (params.stressSourceType === 'SIMPLE') {
        let body = ''
        if (values?.bodyType !== 'NONE') {
          body = JSON.stringify(values?.[values?.bodyType])
        }
        params = {
          ...params,
          threadGroupConfig: JSON.stringify(values?.threadGroupConfig),
          header: JSON.stringify(values?.header),
          body,
          query: JSON.stringify(values?.query),
          assertion: values?.enableAssertionConfig ? JSON.stringify(values?.assertion) : '',
          relation: values?.enableParamConfig ? JSON.stringify(values?.relation) : '',
        }
      } else if (params.stressSourceType === 'JMX') {
        params = {
          ...params,
          threadGroupConfig: '{}',
          header: '[]',
          body: '[]',
          query: '[]',
          assertion: '[]',
          bodyType: '',
          path: '',
          method: '',
          relation: values?.jmx?.enableParamConfig ? JSON.stringify(values?.jmx?.relation) : '',
          jmxUrl: values?.jmx?.jmxUrl ? JSON.stringify(values?.jmx?.jmxUrl) : null,
        }
      }
      const res = await api(params);
      hide();
      if (res?.code === 0) {
        message.success('保存成功');
        if (res?.data?.id) {
          setSearchParams({
            id: res?.data?.id
          })
        }
        refresh()
        return true;
      } else {
        message.error('保存失败请重试！');
        return false;
      }
    } catch (error) {
      hide();
      message.error('保存失败请重试！');
      return false;
    }
  };


  return (
    <ProForm
      loading={loading}
      layout="vertical"
      requiredMark
      submitter={{
        render: (props, dom) => {
          return (
            <FooterToolbar>
              {getErrorInfo(error)}
              <Button onClick={() => {
                history.push('/stress-test/case')
              }}>返回</Button>
              {dom}
            </FooterToolbar>
          );
        },
      }}
      form={form}
      initialValues={{
        stressSourceType: 'SIMPLE',
      }}
      onFinish={onFinish}
      onFinishFailed={onFinishFailed}
    >
      <PageContainer>
        <Card title="用例信息" className={styles.card} bordered={false}>
          <Row gutter={16}>
            <Col lg={6} md={12} sm={24}>
              <ProFormText
                label={'用例名称'}
                name="name"
                rules={[
                  {
                    required: true,
                    message: '请输入用例名称',
                  },
                ]}
                placeholder="请输入用例名称"
              />
            </Col>
            <Col lg={6} md={12} sm={24}>
              <ProFormSelect
                label={'模块'}
                name="moduleId"
                rules={[
                  {
                    required: true,
                    message: '请选择模块',
                  },
                ]}

                request={async () => {
                  const res = await pageModule({
                    current: 1, pageSize: 100,
                    projectId: initialState?.currentProject?.id
                  })

                  return res?.data?.currentData?.map((item: any) => ({
                    label: item?.name,
                    value: item?.id,
                  })) || []
                }}
                placeholder="请选择模块"
              />
            </Col>
            <Col lg={6} md={12} sm={24}>
              <ProFormSelect
                label={'所属环境'}
                name="environmentId"
                rules={[
                  {
                    required: true,
                    message: '请选择所属环境',
                  },
                ]}
                request={async () => {
                  const res = await getEnvPage({current: 1, pageSize: 100})

                  return res?.data?.currentData?.map((item: any) => ({
                    label: item?.name,
                    value: item?.id,
                  }))
                }}
                placeholder="请选择所属环境"
              />
            </Col>


            <Col lg={24} md={24} sm={24}
            >
              <ProFormTextArea
                label={'UI用例描述'}
                name="description"
                style={{marginBottom: 0}}
                placeholder="请输入UI用例描述"
              />
            </Col>
          </Row>
        </Card>

        <Card
          bordered={false}
          className={styles.card}
        >
          <Form.Item
            label="压测类型"
            labelCol={{span: 20}}
            name={'stressSourceType'} style={{marginBottom: 0}}>
            <Segmented size='large' options={[
              {label: '在线自定义', value: 'SIMPLE'},
              {label: '本地上传JMX脚本', value: 'JMX'},
            ]}></Segmented>
          </Form.Item>
        </Card>

        <Form.Item noStyle shouldUpdate={(pre, next) => pre.stressSourceType !== next.stressSourceType}>
          {(form) => {
            if (form.getFieldValue('stressSourceType') === 'SIMPLE') {
              return <SIMPLE form={form}/>
            }
            return <JMX form={form}/>
          }}
        </Form.Item>

      </PageContainer>
    </ProForm>
  );
};
export default AdvancedForm;
